<!--实名认证-->
<template>
  <el-card class="box-card">
    <!--卡片头部-->
    <template #header>
      <div class="card-header">
        <h1>实名信息</h1>
      </div>
    </template>
    <!--提示部分-->
    <div class="tip">
      <el-icon><InfoFilled></InfoFilled></el-icon>
      <p>完成实名认证后才能添加就诊人，正常进行挂号，为了不影响后续步骤，建议提前实名认证。</p>
    </div>
    <!--卡片身体的主体部分:已认证,成功功和未成功的结构-->
    <el-descriptions v-if="userInfo.authStatus == 1"
        class="margin-top"
        size="default"
        :column="1"
        border
    >
      <el-descriptions-item label-align="center" width="30px">
        <template #label>
          <div class="cell-item">用户姓名</div>
        </template>
        {{userInfo.name}}
      </el-descriptions-item>
      <el-descriptions-item label-align="center" width="30px">
        <template #label>
          <div class="cell-item">证件类型</div>
        </template>
        {{userInfo.certificatesType == '10'?'身份证':'户口本'}}
      </el-descriptions-item>
      <el-descriptions-item label-align="center" width="30px">
        <template #label>
          <div class="cell-item">证件号码</div>
        </template>
        {{userInfo.certificatesNo}}
      </el-descriptions-item>
    </el-descriptions>
    <!--未认证的结构-->
    <el-form ref="certificatesFormRef" v-if="userInfo.authStatus == 0" :model="parms" :rules="rules" style="width: 60%;margin: 20px auto" label-width="80">
      <el-form-item prop="name" label="用户姓名">
        <el-input v-model="parms.name" placeholder="请输入用户姓名"></el-input>
      </el-form-item>
      <el-form-item prop="certificatesType" label="证件类型">
        <el-select v-model="parms.certificatesType" placeholder="请选择证件类型" style="width: 100%">
          <el-option  v-for="(item,index) in arrCertificateType" :value="item.value" :label="item.name" :key="index"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="certificatesNo" label="证件号码">
        <el-input v-model="parms.certificatesNo" placeholder="请输入证件号码"></el-input>
      </el-form-item>
      <el-form-item prop="certificatesUrl" label="上传证件">
      <!--
        ction:upload组件向服务器提交图片路径
        limit:照片墙约束图片个数
        on-exceed:超出约束上传照片数量的钩子
        on-success 图片上传成功的钩子,回注入3个参数
       -->
        <el-upload
            ref="upload"
            list-type="picture-card"
            :on-remove="removeHandle"
            :on-preview="handlepictureCardPreview"
            :on-success="successHandle"
            :on-exceed="exceedHandle"
            :limit="1" action="/api/oss/file/fileUpload?fileHost=userAuah"
        >
          <img style="width: 100%;height: 100%" src="../../../src/assets/images/auth_example.png" alt="">
        </el-upload>
        <el-dialog v-model="dialogVisible" >
          <img w-full :src="parms.certificatesUrl" alt="Preview Image" style="width: 100%;height: 100%" />
        </el-dialog>
      </el-form-item>
      <el-form-item>
        <el-button v-on:click="submit" type="primary" size="default" >提交</el-button>
        <el-button v-on:click="reset" size="default">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script setup lang="ts">

import {InfoFilled} from "@element-plus/icons-vue";
import {
  CertificateArr,
  CertificateTypeResponseData,
  UserCertificateParams,
  UserInfoResponseData
} from "@/api/user/type.ts";
import {reqCertificateType, reqUserCertificate, reqUserInfo} from "@/api/user";
import {onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";

//用户信息
let userInfo = ref<any>({})
let arrCertificateType = ref<CertificateArr>()

// 控制对话框的显示与隐藏
let dialogVisible = ref<boolean>(false);

// 收集用户认证的表单数据
let parms = reactive<UserCertificateParams>({
  certificatesNo: "",
  certificatesType: "",
  certificatesUrl: "",
  name: ""
});

// 上传照片功能的实例对象
let upload = ref();

//获取 认证信息 from组件实例
let certificatesFormRef = ref();

//获取用户信息
const getUserInfo = async () => {
  let result: UserInfoResponseData = await reqUserInfo();
  if (result.code == 200) {
    userInfo.value = result.data;
  }
};
//获取证件类型
const setCertificateType = async () => {
  let result: CertificateTypeResponseData = await reqCertificateType();
  if (result.code == 200) {
    arrCertificateType.value = result.data;
  }
};

// 超出上传照片数量的钩子
const exceedHandle = () => {
  ElMessage({
    type: "error",
    message: "照片数量仅为一"
  });
};

// 上传认证照片成功
const successHandle = (response: any, uploadFile:any, uploadFiles: any) => {
  // 如果图片上传成功,清除校验结果,即上传成功后,红色警告字样消失
  certificatesFormRef.value.clearValidate("certificatesUrl");
  // 收集上传成功的后改照片的地址
  parms.certificatesUrl = response.data;
  // 收集上传成功图片地址
  // response:上传图片请求服务器返回的数据
  // uploadFile上传文件对象
}

// 收集上传照片预览的钩子
const handlepictureCardPreview = (uploadFile: any) => {
  // 弹出对话框
  dialogVisible.value = true;
};
//升级上传照片删除的钩子
const removeHandle = () => {
  parms.certificatesUrl = "";
}
// 重置按钮的回调
const reset = () => {
  Object.assign(
      parms,
      {
        certificatesNo: "",
        certificatesType: "",
        certificatesUrl: "",
        name: ""
      }
  );
  // 清除文件上传列表
  upload.value.clearFiles();
}
// 提交认证按钮的回调
const submit = async () => {
  //提交前进行表单校验
  // 返回一个promise,如果整个表单验证失败返回一个失败的promise,后面的提交不在执行
  await certificatesFormRef.value.validate();
  try {
    // 认证成功
    await reqUserCertificate(parms);
    ElMessage({
      type: "success",
      message: "认证成功",
    });
    // 重新获取用户信息
    getUserInfo();
  } catch (error) {
    ElMessage({
      type: "error",
      message: "认证失败",
    });
  }
}

// 自定义交易规则回调, rule规则对象,value表单元素文本内容,callBack放行函数
const validatorName = (rule:any,value:any,callBack:any) => {
  const reg = /^[\u00B7\u3007\u3400-\u4DBF\u4E00-\u9FFF\uE000-\uF8FF\uD840-\uD8C0\uDC00-\uDFFF\uF900-\uFAFF]+$/;
  if (reg.test(value)) {
    callBack();
  } else {
    callBack(new Error("请输入中国姓名"));
  }
}
// 证件类型校验规则回调
const validatorType = (rule:any,value:any,callBack:any) => {
  if (value == "10" || value == "20") {
    callBack();
  } else {
    callBack(new Error("请选择证件类型"));
  }
}
// 证件号码校验规则回调
const validatorNo = (rule:any,value:any,callBack:any) => {
  const SfzReg = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}(\d|x|X)$/; //身份证正则
  const HkbReg = /^\d{9}$/; //户口本正则
  if (SfzReg.test(value) || HkbReg.test(value)) {
    callBack();
  } else {
    callBack(new Error("请输入正确的身份证或户口本号码"));
  }
}
// 证件照图片校验规则回调
const validatorUrl = (rule:any,value:any,callBack:any) => {
  if (value.length) {
    callBack();
  } else {
    callBack(new Error("请上传证件照图片"));
  }
}
// 表单校验规则
const rules = {
  //用户姓名校验规则
  name:[
    {
      required: true, // 表示当前字段必须进行校验且表单左上方会显示红*
      validator: validatorName,
    } ,
  ],
  certificatesType:[
    {
      required: true,
      validator: validatorType,
    } ,
  ],
  certificatesNo:[
    {
      required: true,
      validator: validatorNo,
    } ,
  ],
  certificatesUrl:[
    {
      required: true,
      validator: validatorUrl,
    } ,
  ],
}

onMounted(() => {
  getUserInfo();
  //获取证件类型
  setCertificateType();
});


</script>

<style scoped lang="scss">
.box-card {
  :deep(.el-card__body) {
    .tip {
      color: #7f7f7f;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .margin-top {
      margin: 20px auto;
    }
    .el-descriptions__label {
      //width: 30px !important;
      .cell-item {
        //width: 50px;
      }
    }
  }
}
</style>